package vcsn.ui;

import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.Vector;

import org.eclipse.core.resources.IProject;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;

import vcsn.Config;
import vcsn.Configuration;

public class ConfigurationDialog extends Dialog {
	public IProject project;
	public File configFile;
	public Scanner scn;
	public DataOutputStream  out;
	public Vector<String> peerList;
	public String userName;
	public String userEmail;
	public String remoteURI;
	
	private Shell shell;
	private List listbox;
	private Text txtAddPeer;
	private Text txtUserName;
	private Text txtUserEmail;
	private Text txtRemoteURI;
	private Configuration config; 
	private boolean isPeerListEdited;
	
    public ConfigurationDialog (Shell parent, int style, IProject project) {
            super (parent, style);
            this.project = project;
            configFile = new File(project.getLocation().toString() + File.separator + Config.peerFile);
            if(!configFile.exists()){
            	try {
					configFile.createNewFile();
				} catch (IOException e) {
					e.printStackTrace();
					return;
				}
            }
            config = new Configuration(project.getLocation().toString(), project.getName());
            userName = config.getUserName();
            userEmail = config.getUserEmail();
            remoteURI = config.getRemoteURI();
            peerList = config.getPeerList();
//            userName = Configuration.getAuthor();
//            userEmail = Configuration.getEmail();
            isPeerListEdited = false;
            
    }
    
    public ConfigurationDialog (Shell parent, IProject project) {
            this (parent, SWT.NONE, project); // your default style bits go here (not the Shell's style bits)
    }
    
    public void open () {
            Shell parent = getParent();
            shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
            // Your code goes here (widget creation, set result, etc).
            shell.setText("Configuration");
            shell.setLocation(400, 100);
            shell.setSize(310, 650);
//            System.out.println("x: " + shell.getLocation().x + " y: " + shell.getLocation().y + " width:" + shell.getSize().x + " height: " + shell.getSize().y);
            
            // Initialize layout
            GridLayout layout = new GridLayout();
            layout.marginLeft = 5;
            layout.marginTop = 5;
            layout.marginRight = 5;
            layout.marginBottom = 5;
            layout.numColumns = 2;
            
            shell.setLayout(layout);
            
            // Initialize layout Elements
            GridData gridDataTextConfig = new GridData();
            gridDataTextConfig.widthHint = 270;
            gridDataTextConfig.heightHint = 25;
            gridDataTextConfig.horizontalAlignment = SWT.LEFT;
            gridDataTextConfig.horizontalSpan = 2;
                       
            GridData gridDataListBox = new GridData();
            gridDataListBox.widthHint = 250;
            gridDataListBox.heightHint = 200;
            gridDataListBox.horizontalSpan = 2;
            
            GridData gridDataButton = new GridData();
            gridDataButton.widthHint = 100;
            gridDataButton.heightHint = 30;
            gridDataButton.horizontalAlignment = SWT.END;
            gridDataButton.horizontalSpan = 2;
            
            GridData gridDataSeparatorLabel = new GridData();
            gridDataSeparatorLabel.widthHint = 75;

            GridData gridDataLabeledSeparator = new GridData();
            gridDataLabeledSeparator.widthHint = 200;
                        
            GridData gridDatatxtAddPeer = new GridData();
            gridDatatxtAddPeer.widthHint = 250;
            gridDatatxtAddPeer.heightHint = 30;
            gridDatatxtAddPeer.horizontalAlignment = SWT.LEFT;
            gridDatatxtAddPeer.horizontalSpan = 2;
            
            GridData gridDataSeparator = new GridData();
            gridDataSeparator.widthHint = 275;
            gridDataSeparator.horizontalSpan = 2;
            
            // Initialize Controls
            Label lblAuthor = new Label(shell, SWT.NONE);
            lblAuthor.setText("User Name");
                                    
            Label separator_h0 = new Label(shell, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);
            
            txtUserName = new Text(shell, SWT.NONE);
            txtUserName.setEnabled(true);
            txtUserName.setEditable(true);
            txtUserName.setText(userName);
            txtUserName.setMessage("User Name you want to show.");
            txtUserName.setVisible(true);
            
            Label lblEmail = new Label(shell, SWT.NONE);
            lblEmail.setText("User Email");
                                    
            Label separator_h1 = new Label(shell, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);
            
            txtUserEmail = new Text(shell, SWT.NONE);
            txtUserEmail.setEnabled(true);
            txtUserEmail.setEditable(true);
            txtUserEmail.setText(userEmail);
            txtUserEmail.setMessage("Email address you want to show.");
            txtUserEmail.setVisible(true);
            
            Label lblRemoteURI = new Label(shell, SWT.NONE);
            lblRemoteURI.setText("Remote URL");
                                    
            Label separator_h2 = new Label(shell, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);
            
            txtRemoteURI = new Text(shell, SWT.NONE);
            txtRemoteURI.setEnabled(true);
            txtRemoteURI.setEditable(true);
            txtRemoteURI.setText(remoteURI);
            txtRemoteURI.setMessage("Remote repository location, the full URI including username and password.");
            txtRemoteURI.setVisible(true);
            
            Label lblPeer = new Label(shell, SWT.NONE);
            lblPeer.setText("Peer List");
                                    
            Label separator_h3 = new Label(shell, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);
            
            listbox = new List(shell, SWT.BORDER);
            listbox.setBackground(new Color(Display.getCurrent(), 255, 255, 255));
            listbox.setVisible(true);
            read();
                        
            Button btnRemove = new Button(shell, SWT.PUSH);
            btnRemove.setText("Remove");
            btnRemove.setVisible(true);
            btnRemove.addMouseListener(new MouseListener(){

				@Override
				public void mouseDoubleClick(MouseEvent e) {					
				}

				@Override
				public void mouseDown(MouseEvent e) {				
				}

				@Override
				public void mouseUp(MouseEvent e) {
					delete();
				}
            	
            });
                        
            Label lblAdd = new Label(shell, SWT.NONE);
            lblAdd.setText("Add New");
                                    
            Label separator_h4 = new Label(shell, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);
            
            txtAddPeer = new Text(shell, SWT.NONE);
            txtAddPeer.setEnabled(true);
            txtAddPeer.setEditable(true);
            txtAddPeer.setMessage("IP address you want to add.");
            txtAddPeer.setVisible(true);
                        
            Button btnAdd = new Button(shell, SWT.PUSH);
            btnAdd.setText("Add");
            btnAdd.setVisible(true);
            btnAdd.addMouseListener(new MouseListener(){

				@Override
				public void mouseDoubleClick(MouseEvent e) {					
				}

				@Override
				public void mouseDown(MouseEvent e) {
				}

				@Override
				public void mouseUp(MouseEvent e) {
					add();
				}
            	
            });
                        
            Label separator_h5 = new Label(shell, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);
                        
            Button btnSave = new Button(shell, SWT.PUSH);
            btnSave.setText("Save");
            btnSave.setVisible(true);
            btnSave.addMouseListener(new MouseListener(){

				@Override
				public void mouseDoubleClick(MouseEvent e) {
				}

				@Override
				public void mouseDown(MouseEvent e) {
				}

				@Override
				public void mouseUp(MouseEvent e) {
					save();
				}
            	
            });
            
            Button btnCancel = new Button(shell, SWT.PUSH);
            btnCancel.setText("Cancel");
            btnCancel.setVisible(true);
            btnCancel.addMouseListener(new MouseListener(){

				@Override
				public void mouseDoubleClick(MouseEvent e) {
				}

				@Override
				public void mouseDown(MouseEvent e) {
				}

				@Override
				public void mouseUp(MouseEvent e) {
					cancel();
				}
            	
            });
            
            // Appending controls to layout elements
            
            lblAuthor.setLayoutData(gridDataSeparatorLabel);
            separator_h0.setLayoutData(gridDataLabeledSeparator);
            
            txtUserName.setLayoutData(gridDataTextConfig);
            
            lblEmail.setLayoutData(gridDataSeparatorLabel);
            separator_h1.setLayoutData(gridDataLabeledSeparator);
            
            txtUserEmail.setLayoutData(gridDataTextConfig);
            
            lblRemoteURI.setLayoutData(gridDataSeparatorLabel);
            separator_h2.setLayoutData(gridDataLabeledSeparator);
            
            txtRemoteURI.setLayoutData(gridDataTextConfig);
            
            lblPeer.setLayoutData(gridDataSeparatorLabel);
            separator_h3.setLayoutData(gridDataLabeledSeparator);
            listbox.setLayoutData(gridDataListBox);
            
            btnRemove.setLayoutData(gridDataButton);
            
            lblAdd.setLayoutData(gridDataSeparatorLabel);
            separator_h4.setLayoutData(gridDataLabeledSeparator);
            
            txtAddPeer.setLayoutData(gridDatatxtAddPeer);
            
            btnAdd.setLayoutData(gridDataButton);
            
            separator_h5.setLayoutData(gridDataSeparator);
            
            btnSave.setLayoutData(gridDataButton);
            btnCancel.setLayoutData(gridDataButton);
            
            shell.open();
            Display display = parent.getDisplay();
            while (!shell.isDisposed()) {
                    if (!display.readAndDispatch()) display.sleep();
            }
    }
    
    public void read() {
    	for(String str : peerList)
    		listbox.add(str);
    }
    
    public void delete() {
    	if(listbox.getSelectionCount() <= 0){
    		MessageBox msgBox = new MessageBox(shell, SWT.ICON_ERROR);
    		msgBox.setMessage("No Item is selcted");
    		msgBox.open();
    	}else{
    		for(String str : listbox.getSelection()){
    			this.peerList.remove(str);
    			listbox.remove(str);
    			isPeerListEdited = true;
    		}
    	}
    }
    
    //"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
    public void add(){
    	if(txtAddPeer.getText().matches("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")){
	    	peerList.add(txtAddPeer.getText());
	    	listbox.add(txtAddPeer.getText());
    	}else{
    		MessageBox msgBox = new MessageBox(shell, SWT.ICON_ERROR);
    		msgBox.setMessage("Invalid Address.");
    		msgBox.open();
    	}
	    txtAddPeer.setText("");
	    isPeerListEdited = true;
    }
    
    public void save(){
    	if(!txtUserName.getText().equals(userName)){
    		config.setUserName(txtUserName.getText());
    	}
    	if(!txtUserEmail.getText().equals(userEmail)){
    		config.setUserEmail(txtUserEmail.getText());
    	}
    	if(!txtRemoteURI.getText().equals(remoteURI)){
    		config.setRemoteURI(txtRemoteURI.getText());
    	}
    	if(!config.isMergeConfigExist()){
    		config.setMergeSection();
    	}
    	if(isPeerListEdited){
    		config.setPeerList(peerList);
    	}
    	cancel();
    }
    
    public void cancel(){
    	shell.dispose();
    }

}